package com.xu.security.filter;

import com.xu.security.constant.Constants;
import com.xu.security.token.TokenService;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

/**
 * token校验过滤器
 *
 * @Author: 许乾伟
 * @Date: 2024/2/27 11:10
 */
@Component
public class AuthenticationTokenFilter extends OncePerRequestFilter {
    @Resource
    TokenService tokenService;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //获取token
        String authorization = request.getHeader(Constants.TOKEN_AUTH_HEADER);
        if (!StringUtils.hasText(authorization)) {
            //这里放行过后,后面还有filterSercurityIntercept or过滤器会去判断是否认证
            filterChain.doFilter(request, response);
            //不让没通过filterSercurityInterceptor过滤器的请求再次去执行下面的代码,所以return
            return;
        }
        //token 格式校验
        if (!authorization.toLowerCase().startsWith(Constants.BEARER_TYPE.toLowerCase())) {
            filterChain.doFilter(request, response);
            //不让没通过filterSercurityInterceptor过滤器的请求再次去执行下面的代码,所以return
            return;
        }
        //token 有效性校验
        String token = authorization.substring(Constants.BEARER_TYPE.length()).trim();
        if (!tokenService.verifyToken(token)) {
            filterChain.doFilter(request, response);
            //不让没通过filterSercurityInterceptor过滤器的请求再次去执行下面的代码,所以return
            return;
        }
        //用户信息校验
        UserDetails onlineUser = tokenService.getOnlineUserByToken(token);
        if (onlineUser == null) {
            filterChain.doFilter(request, response);
            //不让没通过filterSercurityInterceptor过滤器的请求再次去执行下面的代码,所以return
            return;
        }
        //刷新token
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(onlineUser, null, onlineUser.getAuthorities());
        authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        filterChain.doFilter(request, response);
    }
    
}
